#pragma once
#include "macro_define.h"
#include <memory>
#include <atomic>

class FramePool;
class Frame
{
	friend class FrameWrapper;
public:
	Frame(FramePool& pool_, char* data_, size_t size_, bool isFromPool_)
		: pool(pool_), data(data_), size(size_), isFromPool(isFromPool_) {}
	~Frame();
	Frame(const Frame&) = delete;
	Frame& operator=(const Frame&) = delete;
	void ReturnFrame();
	bool IsFromPool() const { return isFromPool; }
protected:
	void Reset()
	{
		memset(data, 0, size);
		used = 0;
	}
	char* data{ nullptr };
	const size_t size;
	size_t used{ 0 };
	FramePool& pool;
	bool isFromPool{ true };
};

class FrameWrapper final
{
public:
	explicit FrameWrapper(Frame* f) : frame(f) { ASSERT(frame != nullptr); }
	~FrameWrapper();
	FrameWrapper(const FrameWrapper&) = delete;
	FrameWrapper& operator=(const FrameWrapper&) = delete;
	int Assign(char* buf, size_t len);
	size_t GetUsed() const { return frame->used; }
	void ReturnFrame();
private:
	std::atomic_bool hasReturned{ false };
	Frame* frame{ nullptr };
};
using FramePtr = std::shared_ptr<FrameWrapper>;